﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ingr.Yu;
using System.Data;
using Llama;
namespace QualityCheck
{
    public class Main
    {
        PID MyPIDConn;
        LMDrawings objDrawings;
        public Main()
        {

        }
        public Main(PID _pidConn, LMDrawings _objDrawings)
        {
            MyPIDConn = _pidConn;
            objDrawings = _objDrawings;
        }


        ///

        /// <summary>
        /// 最正常的情况,在线上有个break
        /// </summary>
        /// <param name="curGroupIDs">属性完全相同的一组run的SPID</param>
        /// <param name="dtBranchs">spid中查到所有的分支rep（断点两边的线也认为是分支）</param>
        /// <param name="dtRunsOnBranch">每个分支关联的若干个connector</param>
        void CheckRedundantBreak_Break1(List<string> curGroupIDs, DataTable dtBranchs, DataTable dtRunsOnBranch, string dwgName, ref DataTable resDt)
        {
            #region 最正常的情况
            if (curGroupIDs.Count() > 1)
            {
                var IDs = "";
                IDs = string.Join(",", curGroupIDs);
                var Branchs = dtBranchs.Select($"SP_modelitemID in ({IDs})");
                // var spIds = new HashSet<string>();

                for (int xx = 0; xx < Branchs.Count(); xx++)
                {
                    //string spId = Branchs[xx]["sp_id"].ToString();
                    var BranchRes = dtRunsOnBranch.Select($"sp_connectitem1id = '{Branchs[xx]["sp_id"]}' or sp_connectitem2id = '{Branchs[xx]["sp_id"]}'");
                    if (BranchRes.Count() != 3) //3个是正常情况，不是有断点的那种'
                    {
                        var runIDs = "";

                        foreach (DataRow run in BranchRes)
                        {
                            runIDs += run["sp_id"] + ",";
                        }


                        var newRow = resDt.NewRow();
                        //newRow["对象类型"] = "PipeRun";
                        newRow["现有ItemTag"] = BranchRes[0]["itemtag"];
                        newRow["RepID"] = Branchs[xx]["sp_id"]; //'这个是representation ID，不是SPID
                        newRow["所在图纸"] = dwgName;
                        newRow["备注"] = "此处有不必要的打断。";

                        if (BranchRes.Count() == 1)
                        {
                            newRow["断点1侧RunID"] = BranchRes[0]["sp_id"].ToString();
                        }
                        else if (BranchRes.Count() == 2)
                        {
                            newRow["断点1侧RunID"] = BranchRes[0]["sp_id"].ToString();
                            newRow["断点2侧RunID"] = BranchRes[1]["sp_id"].ToString();
                        }
                        resDt.Rows.Add(newRow);
                    }
                    else if (BranchRes.Count() == 3)
                    {
                        String v = Branchs[xx]["sp_id"].ToString();

                        var query = dtRunsOnBranch.AsEnumerable().Where(row => row.Field<string>("sp_connectitem1id") == v || row.Field<string>("sp_connectitem2id") == v).Select(row => row.Field<string>("sp_id")).Distinct().ToList();
                        if (query.Count() == 3)

                        {
                            var runIDs = "";

                            foreach (DataRow run in BranchRes)
                            {
                                runIDs += run["sp_id"] + ",";
                            }


                            var newRow = resDt.NewRow();
                            //newRow["对象类型"] = "PipeRun";
                            newRow["现有ItemTag"] = BranchRes[0]["itemtag"];
                            newRow["RepID"] = Branchs[xx]["sp_id"]; //'这个是representation ID，不是SPID
                            newRow["所在图纸"] = dwgName;
                            newRow["备注"] = "此处有不必要的打断。";

                            if (BranchRes.Count() == 1)
                            {
                                newRow["断点1侧RunID"] = BranchRes[0]["sp_id"].ToString();
                            }
                            else if (BranchRes.Count() == 2)
                            {
                                newRow["断点1侧RunID"] = BranchRes[0]["sp_id"].ToString();
                                newRow["断点2侧RunID"] = BranchRes[1]["sp_id"].ToString();
                            }
                            resDt.Rows.Add(newRow);
                        }
                    }



                }
            }

            #endregion

        }
        /// <summary>
        /// 检查冗余断点（包括线上的，阀门两边的）
        /// </summary>
        /// <returns></returns>
        public DataTable CheckRedundantBreak()
        {
            const string funcName = "冗余断点";
            //var dsResult = new DataSet();
            string sql = "";
            var dtProps_PipeRun = new DataTable();
            #region 从数据字典 获取管子上的属性
            string sqlProps = "";
            sql = $@"SELECT t.unique_name,t2.entity_name FROM xxxSchemaName.uniqueatts t
join xxxSchemaName.entities t2 on t.entity_number = t2.entity_number
where t2.entity_number in (4,22,29) and t.unique_name not like 'SP_%' AND t.unique_name not like '%.%' and t.unique_name != 'UpdateCount'
order by t.unique_name";
            MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDAppDictionary_User, sql, out dtProps_PipeRun);
            foreach (DataRow drProp in dtProps_PipeRun.Rows)
            {
                sqlProps += "," + drProp[1] + "." + drProp[0];
            }

            sqlProps = sqlProps.Substring(1);//去掉第一个逗号
            #endregion

            var resDt = new DataTable();
            resDt.TableName = funcName;
            //resDt.Columns.Add("对象类型"); //2023 12 11 陈玉娟不需要
            resDt.Columns.Add("现有ItemTag");
            resDt.Columns.Add("RepID");
            resDt.Columns.Add("所在图纸");
            resDt.Columns.Add("断点1侧RunID");
            resDt.Columns.Add("断点2侧RunID");
            //resDt.Columns.Add("管径");//2023 12 11 陈玉娟不需要
            //resDt.Columns.Add("等级");//2023 12 11 陈玉娟不需要
            resDt.Columns.Add("备注");

            foreach (LMDrawing objDrawing in objDrawings)
            {
                string dwgName = objDrawing.Attributes["name"].get_Value();
                var dtRuns = new DataTable();
                var dtRunsNoID = new DataTable();
                var dtBranchs = new DataTable();
                var dtRunsOnBranch = new DataTable();
                var dtValveRel = new DataTable();
                try
                {
                    sql = $@"SELECT t_piperun.SP_ID,{sqlProps}
FROM xxxSchemaName.t_piperun
join xxxSchemaName.t_modelitem on t_modelitem.sp_id = t_piperun.sp_id
join xxxSchemaName.t_plantitem on t_plantitem.sp_id = t_modelitem.sp_id
join xxxSchemaName.t_representation t4 on t4.sp_modelitemid = t_piperun.sp_id
join xxxSchemaName.t_drawing t5 on t5.sp_id = t4.sp_drawingid where t5.name = '{dwgName}' and t4.representationtype = '13' 
AND (T_ModelItem.Description != 'Capillary' OR T_ModelItem.Description IS NULL)
AND (T_PipeRun.PipeRunClass != 2 OR
 (T_PipeRun.PipeRunClass =2 and T_PipeRun.PipeRunType=2))
order by { sqlProps}                    ";
                    //PipeRunClass = 1,为管子；
                    //PipeRunClass = 2，PipeRunClass =2 为Instrument下的conn to process
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtRuns);
                    //------按宁波院的意思，除了SPID之外的都相同才算一样，所以这个dtRunsNoID的列估计要改一改-----------------------

                    sql = $@"SELECT {sqlProps}
FROM xxxSchemaName.t_piperun
join xxxSchemaName.t_modelitem on t_modelitem.sp_id = t_piperun.sp_id
join xxxSchemaName.t_plantitem on t_plantitem.sp_id = t_modelitem.sp_id
join xxxSchemaName.t_representation t4 on t4.sp_modelitemid = t_piperun.sp_id
join xxxSchemaName.t_drawing t5 on t5.sp_id = t4.sp_drawingid where t5.name = '{dwgName}' and t4.representationtype = '13'
AND  (T_ModelItem.Description != 'Capillary' OR T_ModelItem.Description IS NULL)
AND (T_PipeRun.PipeRunClass != 2 OR
 (T_PipeRun.PipeRunClass =2 and T_PipeRun.PipeRunType=2))
order by { sqlProps}           ";
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtRunsNoID);
                    //noID 指的没有查sp_id，记录和dtRuns是一致的，除了先后顺序

                    if (dtRunsNoID.Rows.Count == 0)
                    {
                        continue;
                    }

                    sql = $@"select t.sp_id,t.graphicoid,SP_modelitemID
from xxxSchemaName.t_representation t
where t.sp_drawingid = '{objDrawing.Id}' and t.representationtype = 46 ";
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtBranchs); //'根据spid查到所有的分支rep（断点两边的线也认为是分支）

                    sql = $@"select t3.itemtag,t3.sp_id,t.sp_connectitem1id,t.sp_connectitem2id
from xxxSchemaName.t_connector t
join xxxSchemaName.t_representation t2 on t2.sp_id = t.sp_id
join xxxSchemaName.t_plantitem t3 on t3.sp_id = t2.sp_modelitemid
where t2.sp_drawingid = '{objDrawing.Id}'";

                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtRunsOnBranch);// '每个分支关联的若干个connector

                    sql = $@"SELECT T.SP_ID,T.SP_MODELITEMID,T3.ITEMTAG,T4.SP_MODELITEMID RUN1ID,T5.SP_MODELITEMID RUN2ID
FROM xxxSchemaName.T_REPRESENTATION T
JOIN xxxSchemaName.T_PLANTITEM T3 ON T3.SP_ID = T.SP_MODELITEMID
LEFT JOIN xxxSchemaName.T_RELATIONSHIP R1 ON R1.SP_ITEM1ID = T.SP_ID
LEFT JOIN xxxSchemaName.T_REPRESENTATION T4 ON T4.SP_ID = R1.SP_ITEM2ID
LEFT JOIN xxxSchemaName.T_RELATIONSHIP R2 ON R2.SP_ITEM2ID = T.SP_ID
LEFT JOIN xxxSchemaName.T_REPRESENTATION T5 ON T5.SP_ID = R2.SP_ITEM1ID
WHERE T.REPRESENTATIONTYPE = '13' AND T.SP_DRAWINGID = '{objDrawing.Id}'";
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtValveRel);// '每个元件（如阀门）两边的connid。2023 12 9 陈玉娟的需求
                    //过滤掉一些不需要的东西，以免后面误判
                    var dtValveIDs = dtValveRel.AsEnumerable().Select(x => x["SP_MODELITEMID"].ToString()).Distinct().ToList();
                    foreach (var drValveID in dtValveIDs)
                    {
                        var rels = dtValveRel.AsEnumerable().Where(x => x["SP_MODELITEMID"].ToString() == drValveID);
                        if (rels.Count() == 1 && rels.ElementAt(0)["RUN1ID"].ToString() == rels.ElementAt(0)["RUN2ID"].ToString())
                        {
                            //正常在管子上的元件，两边的spid是一致的
                            dtValveRel.Rows.Remove(rels.ElementAt(0));
                            dtValveRel.AcceptChanges();
                        }
                        else if (rels.Count() == 2)
                        {
                            if ((rels.ElementAt(0)["RUN1ID"].ToString() == rels.ElementAt(1)["RUN2ID"].ToString()) ||
                            (rels.ElementAt(0)["RUN1ID"].ToString() == rels.ElementAt(1)["RUN1ID"].ToString() && !string.IsNullOrEmpty(rels.ElementAt(0)["RUN1ID"].ToString())) ||
                            (rels.ElementAt(0)["RUN2ID"].ToString() == rels.ElementAt(1)["RUN1ID"].ToString()) ||
                            (rels.ElementAt(0)["RUN2ID"].ToString() == rels.ElementAt(1)["RUN2ID"].ToString() && !string.IsNullOrEmpty(rels.ElementAt(0)["RUN2ID"].ToString()))
                            )
                            {
                                dtValveRel.Rows.Remove(rels.ElementAt(0));
                                dtValveRel.AcceptChanges();
                                dtValveRel.Rows.Remove(rels.ElementAt(0));//第一次remove后，连这个rels本身也受影响，所以不能removeat 1
                                dtValveRel.AcceptChanges();
                            }
                        }
                    }
                }
                catch (Exception EX)
                {
                    throw new Exception("无法查询管道信息.");
                }

                var curGroupCondition = dtRunsNoID.Rows[0];// '用于比较用
                List<string> curGroupIDs = new List<string>();//当前属性相同的一组run的id的集合
                curGroupIDs.Add("'" + dtRuns.Rows[0]["SP_ID"] + "'");

                for (int i = 1; i < dtRunsNoID.Rows.Count; i++) //0 一开始已经是 curGroupCondition了
                {
                    for (int col = 0; col < dtRunsNoID.Columns.Count; col++)
                    {
                        if (curGroupCondition[col].ToString() != dtRunsNoID.Rows[i][col].ToString()) //值不一样，就说明属于不同的组，然后去处理之前一组里的所有pipe run
                        {
                            //'当前组进行处理
                            if (curGroupIDs.Count > 1)
                            {
                                var IDs = "";
                                IDs = string.Join(",", curGroupIDs);
                                var Branchs = dtBranchs.Select($"SP_modelitemID in ({IDs})");
                                if (Branchs.Count() > 0)
                                {
                                    CheckRedundantBreak_Break1(curGroupIDs, dtBranchs, dtRunsOnBranch, dwgName, ref resDt);
                                }
                                CheckRedundantBreak_Break2(curGroupIDs, dtValveRel, dwgName, ref resDt);
                                Branchs = null;
                            }

                            //进入到下一组
                            //Debug.Print("当前组的行：" + i.ToString)
                            curGroupCondition = dtRunsNoID.Rows[i];
                            curGroupIDs.Clear();
                            continue; //'去下面的add
                        }
                    }

                    curGroupIDs.Add("'" + dtRuns.Rows[i]["SP_ID"] + "'");
                }


                if (curGroupIDs.Count > 1)
                {
                    var IDs = "";
                    IDs = string.Join(",", curGroupIDs);
                    var Branchs = dtBranchs.Select($"SP_modelitemID in ({IDs})");
                    if (Branchs.Count() > 0)
                    {
                        CheckRedundantBreak_Break1(curGroupIDs, dtBranchs, dtRunsOnBranch, dwgName, ref resDt);
                    }
                    CheckRedundantBreak_Break2(curGroupIDs, dtValveRel, dwgName, ref resDt);
                }


                dtRuns = null;
                dtRunsNoID = null;
                dtBranchs = null;
                dtRunsOnBranch = null;
                dtValveRel = null;
            }

            //dsResult.Tables.Clear();
            //dsResult.Tables.Add(resDt);
            return resDt;
        }

        /// <summary>
        /// 阀门或者阀门两边的情况
        /// </summary>
        /// <param name="curGroupIDs">属性完全相同的一组run的SPID</param>
        /// <param name="dtValveRel"></param>
        /// <param name="dtRunsOnBranch"></param>
        /// <param name="dwgName"></param>
        /// <param name="resDt"></param>
        void CheckRedundantBreak_Break2(List<string> curGroupIDs, DataTable dtValveRel,  string dwgName, ref DataTable resDt)
        {

            #region 阀门或者阀门两边的
            for (int conn1 = 0; conn1 < curGroupIDs.Count - 1; conn1++)
            {
                for (int conn2 = conn1 + 1; conn2 < curGroupIDs.Count; conn2++)
                {
                    var found = false;
                    var RelRes = dtValveRel.Select($"(RUN1ID = {curGroupIDs[conn1]} and RUN2ID = {curGroupIDs[conn2]}) or (RUN2ID = {curGroupIDs[conn1]} and RUN1ID = {curGroupIDs[conn2]})");
                    if (RelRes.Count() == 1)
                    {
                        found = true;
                    }
                    else
                    {
                        RelRes = dtValveRel.Select($"RUN1ID = {curGroupIDs[conn1]} or RUN1ID = {curGroupIDs[conn2]}");//需要再添加个筛选。

                        if (RelRes.Count() == 2 && RelRes[0]["SP_MODELITEMID"].ToString() == RelRes[1]["SP_MODELITEMID"].ToString())
                        {
                            found = true;
                        }
                        else
                        {
                            RelRes = dtValveRel.Select($"RUN2ID = {curGroupIDs[conn1]} or RUN2ID = {curGroupIDs[conn2]}");
                            if (RelRes.Count() == 2 && RelRes[0]["SP_MODELITEMID"].ToString() == RelRes[1]["SP_MODELITEMID"].ToString())
                            {
                                found = true;

                            }
                            else
                            {
                                var V_DT = dtValveRel.Select($"RUN1ID = {curGroupIDs[conn1]} or RUN1ID = {curGroupIDs[conn2]}");
                                if (V_DT.Length != 2)//可能·多余
                                {
                                    var G_V_DTS = V_DT.GroupBy(r => r["SP_MODELITEMID"].ToString()).ToList();
                                    for (int i = 0; i < G_V_DTS.Count(); i++)
                                    {
                                        var spModelItemId = G_V_DTS[i].Key;
                                        RelRes = dtValveRel.Select($"(RUN1ID = {curGroupIDs[conn1]} or RUN1ID = {curGroupIDs[conn2]}) and SP_MODELITEMID = '{spModelItemId}'");
                                        if (RelRes.Count() == 2 && RelRes[0]["SP_MODELITEMID"].ToString() == RelRes[1]["SP_MODELITEMID"].ToString())
                                        {
                                            var newRow = resDt.NewRow();
                                            //newRow["对象类型"] = "PipeRun";
                                            newRow["现有ItemTag"] = RelRes[0]["ITEMTAG"].ToString();
                                            newRow["RepID"] = RelRes[0]["SP_ID"].ToString();// '需要的是rep id，这样才能定位跳转
                                            newRow["所在图纸"] = dwgName;
                                            newRow["备注"] = "此处的元件两侧，有不必要的打断。";
                                            newRow["断点1侧RunID"] = curGroupIDs[conn1];
                                            newRow["断点2侧RunID"] = curGroupIDs[conn2];
                                            resDt.Rows.Add(newRow);
                                        }
                                        else
                                        {
                                            RelRes = dtValveRel.Select($"(RUN2ID = {curGroupIDs[conn1]} or RUN2ID = {curGroupIDs[conn2]}) and SP_MODELITEMID = '{spModelItemId}'");
                                            if (RelRes.Count() == 2 && RelRes[0]["SP_MODELITEMID"].ToString() == RelRes[1]["SP_MODELITEMID"].ToString())
                                            {
                                                var newRow = resDt.NewRow();
                                                //newRow["对象类型"] = "PipeRun";
                                                newRow["现有ItemTag"] = RelRes[0]["ITEMTAG"].ToString();
                                                newRow["RepID"] = RelRes[0]["SP_ID"].ToString();// '需要的是rep id，这样才能定位跳转
                                                newRow["所在图纸"] = dwgName;
                                                newRow["备注"] = "此处的元件两侧，有不必要的打断。";
                                                newRow["断点1侧RunID"] = curGroupIDs[conn1];
                                                newRow["断点2侧RunID"] = curGroupIDs[conn2];
                                                resDt.Rows.Add(newRow);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (found)
                    {
                        var newRow = resDt.NewRow();
                        //newRow["对象类型"] = "PipeRun";
                        newRow["现有ItemTag"] = RelRes[0]["ITEMTAG"].ToString();
                        newRow["RepID"] = RelRes[0]["SP_ID"].ToString();// '需要的是rep id，这样才能定位跳转
                        newRow["所在图纸"] = dwgName;
                        newRow["备注"] = "此处的元件两侧，有不必要的打断。";
                        newRow["断点1侧RunID"] = curGroupIDs[conn1];
                        newRow["断点2侧RunID"] = curGroupIDs[conn2];
                        resDt.Rows.Add(newRow);
                    }

                }

            }
            #endregion

        }

        /// <summary>
        /// 检查流向
        /// </summary>
        /// <returns></returns>
        public DataTable CheckFlowDir()
        {
            const string funcName = "流向";
            //var dsResult = new DataSet();
            string sql = "";

            var resDt = new DataTable(funcName);
            var dtRuns = new DataTable();
            var dtConns = new DataTable();
            try
            {
                //resDt.Columns.Add("对象类型"); //2023 12 11 陈玉娟不需要
                resDt.Columns.Add("现有ItemTag");
                resDt.Columns.Add("RepID");
                resDt.Columns.Add("所在图纸");
                resDt.Columns.Add("SP_ID");//2023 12 11 陈玉娟不需要
                //resDt.Columns.Add("等级");//2023 12 11 陈玉娟不需要
                resDt.Columns.Add("备注");
                foreach (LMDrawing objDrawing in objDrawings)
                {
                    dtRuns = new DataTable();
                    dtConns = new DataTable();
                    string dwgName = objDrawing.Attributes["name"].get_Value();
                    sql = $@"SELECT T.SP_ID,T3.ITEMTAG,T.FLOWDIRECTION FROM xxxSchemaName.T_PIPERUN T
JOIN xxxSchemaName.T_PLANTITEM T3 ON T3.SP_ID=T.SP_ID
JOIN xxxSchemaName.T_REPRESENTATION T2 ON T2.SP_MODELITEMID=T.SP_ID
WHERE T2.SP_DRAWINGID='{objDrawing.Id}' AND T2.REPRESENTATIONTYPE='13'";
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtRuns);
                    sql = $@"SELECT T.SP_ID,T3.ITEMTAG,T.FLOWDIRECTION,T2.SP_ID REPID FROM xxxSchemaName.T_PIPERUN T
JOIN xxxSchemaName.T_PLANTITEM T3 ON T3.SP_ID=T.SP_ID
JOIN xxxSchemaName.T_REPRESENTATION T2 ON T2.SP_MODELITEMID=T.SP_ID
WHERE T2.SP_DRAWINGID='{objDrawing.Id}' AND T2.REPRESENTATIONTYPE='9'";
                    MyPIDConn.PIDReadDataByDBA(MyPIDConn.PIDPlant_DBNAME, MyPIDConn.ActivePlantPIDApp_User, sql, out dtConns);
                    foreach (DataRow runNoFlow in dtRuns.AsEnumerable().Where(X => string.IsNullOrEmpty(X["FLOWDIRECTION"].ToString())))
                    {
                        var newRow = resDt.NewRow();
                        newRow["现有ItemTag"] = runNoFlow["ITEMTAG"].ToString();
                        newRow["SP_ID"] = runNoFlow["SP_ID"].ToString();
                        newRow["所在图纸"] = dwgName;
                        newRow["备注"] = "该管线无流向";

                        var conn = dtConns.AsEnumerable().FirstOrDefault(x => x["SP_ID"].ToString() == runNoFlow["SP_ID"].ToString());

                        if (conn != null)
                        {
                            newRow["RepID"] = conn["REPID"].ToString();
                        }

                        resDt.Rows.Add(newRow);
                    }
                    dtRuns = null;
                    dtConns = null;
                }

            }
            catch (Exception ex)
            {
                resDt.Columns.Clear();
                resDt.Rows.Clear();
                resDt.Columns.Add("查询出错。");
                var newRow = resDt.NewRow();
                newRow[0] = ex.Message + "\r\n" + ex.StackTrace;
                resDt.Rows.Add(newRow);
            }

            return resDt;
        }
        public DataSet Start()
        {
            var dsResult = new DataSet();
            dsResult.Tables.Add(CheckRedundantBreak());
            dsResult.Tables.Add(CheckFlowDir());
            return dsResult;
        }
    }
}
